#include <OgreException.h>

#ifndef Painful_Code
#define Painful_Code

void call_ehandler(Ogre::Exception* e);

template<class type, class ret>
ret call0(type *pClass, ret(type::* funcptr)(void))
{
    try
    {
        return (pClass->*funcptr)();
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
		return NULL;
    }
}

template<class type, class ret>
ret call0_v(type *pClass, ret(type::* funcptr)(void))
{
    try
    {
        return (pClass->*funcptr)();
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
    }
}

template<class atype1, class type, class ret>
ret call1(type *pClass, ret(type::* funcptr)(atype1), atype1 arg)
{
    try
    {
        return (pClass->*funcptr)(arg);
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
		return NULL;
    }
}

template<class atype1, class type, class ret>
ret call1_v(type *pClass, ret(type::* funcptr)(atype1), atype1 arg)
{
    try
    {
        return (pClass->*funcptr)(arg);
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
    }
}

template<class atype1, class atype2, class type, class ret>
ret call2(type *pClass, ret(type::* funcptr)(atype1, atype2), atype1 arg, atype2 arg2)
{
    try
    {
        return (pClass->*funcptr)(arg, arg2);
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
		return NULL;
    }
}

template<class atype1, class atype2, class type, class ret>
ret call2_v(type *pClass, ret(type::* funcptr)(atype1, atype2), atype1 arg, atype2 arg2)
{
    try
    {
        return (pClass->*funcptr)(arg, arg2);
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
    }
}

template<class atype1, class atype2, class atype3, class type, class ret>
ret call3(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3), atype1 arg, atype2 arg2, atype3 arg3)
{
    try
    {
        return (pClass->*funcptr)(arg, arg2, arg3);
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
		return NULL;
    }
}

template<class atype1, class atype2, class atype3, class type, class ret>
ret call3_v(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3), atype1 arg, atype2 arg2, atype3 arg3)
{
    try
    {
        return (pClass->*funcptr)(arg, arg2, arg3);
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
    }
}

template<class atype1, class atype2, class atype3, class atype4, class type, class ret>
ret call4_v(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3, atype4), atype1 arg, atype2 arg2, atype3 arg3, atype4 arg4)
{
    try
    {
        return (pClass->*funcptr)(arg, arg2, arg3, arg4);
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
    }
}

template<class atype1, class atype2, class atype3, class atype4, class type, class ret>
ret call4(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3, atype4), atype1 arg, atype2 arg2, atype3 arg3, atype4 arg4)
{
    try
    {
        return (pClass->*funcptr)(arg, arg2, arg3, arg4);
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
		return NULL;
    }
}

template<class atype1, class atype2, class atype3, class atype4, class atype5, class type, class ret>
ret call5(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3, atype4, atype5), atype1 arg, atype2 arg2, atype3 arg3, atype4 arg4, atype5 arg5)
{
    try
    {
        return (pClass->*funcptr)(arg, arg2, arg3, arg4, arg5);
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
		return NULL;
    }
}

template<class atype1, class atype2, class atype3, class atype4, class atype5, class type, class ret>
ret call5_v(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3, atype4, atype5), atype1 arg, atype2 arg2, atype3 arg3, atype4 arg4, atype5 arg5)
{
    try
    {
        return (pClass->*funcptr)(arg, arg2, arg3, arg4, arg5);
    }
    catch(const Ogre::Exception& e)
	{
        call_ehandler((Ogre::Exception*)&e);
    }
}
#endif
